package com.ww.springboot.rabbitmq.mq;

import cn.hutool.json.JSONUtil;
import com.ww.springboot.rabbitmq.dto.ExpServiceMsg;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import java.util.UUID;


@Service
public class MessageSenderImpl implements MessageSender {

    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private AmqpAdmin amqpAdmin;

    private final Double DEFAULT_TIMEOUT = 6000D;

    @Override
    public void send(QueueConstants.QueueEnum queueEnum, ExpServiceMsg expServiceMsg) {
        //有事务的话,事务处理完后再发送MQ
        TransactionSynchronizationManager
                .registerSynchronization(new TransactionSynchronizationAdapter() {
                                             @Override
                                             public void afterCommit() {
                                                 rabbitTemplate.convertAndSend(queueEnum.getExchangeEnum().getExchangeName(), queueEnum.getRoutingKey(), expServiceMsg);
                                             }
                                         }
                );

    }

    @Override
    public void sendRetry(QueueConstants.QueueEnum queueEnum, ExpServiceMsg expServiceMsg) {
        //失败后进来新建异常一个处理队列和交换机
        String orgRoutingKey = queueEnum.getRoutingKey();
        String orgExchangeName = queueEnum.getExchangeEnum().getExchangeName();
        String waitingQueueName = queueEnum.getRoutingKey() + "retry";
        Double expiration = DEFAULT_TIMEOUT * Math.pow(2, expServiceMsg.getMsgCount());

        Queue retryQueue = QueueBuilder.nonDurable(waitingQueueName)
                .withArgument(QueueConstants.DEAD_LETTER_EX,
                        orgExchangeName) // DLX，dead letter发送到的exchange
                .withArgument(QueueConstants.DEAD_LETTER_ROUTING_KEY, orgRoutingKey)
//                .withArgument(QueueConstants.DEAD_LETTER_TIMEOUT,
//                    expiration.intValue()) // 设置队列的过期时间
                .autoDelete()
                .build();
        amqpAdmin.declareQueue(retryQueue);
        Exchange exchange = ExchangeBuilder.directExchange(orgExchangeName)
                .durable(true)
                .build();
        amqpAdmin.declareExchange(exchange);
        amqpAdmin.declareBinding(
                BindingBuilder.bind(retryQueue).to(exchange).with(waitingQueueName).noargs());

        MessageBuilderSupport<Message> messageMessageBuilderSupport = MessageBuilder.withBody(JSONUtil.toJsonStr(expServiceMsg).getBytes())
                .setContentType(MessageProperties.CONTENT_TYPE_JSON)
                .setContentEncoding("UTF-8");
        Message message = messageMessageBuilderSupport.build();
        message.getMessageProperties().setExpiration(String.valueOf(expiration.intValue()));


        rabbitTemplate
                .convertAndSend(orgExchangeName, waitingQueueName, message);
    }

}
